package demo;

import java.util.PriorityQueue;
import java.util.Timer;
import java.util.TimerTask;

/**
 * 模拟实现定时器
 */
class MyTimerTask implements Comparable<MyTimerTask> {
    private Runnable runnable;
    private long time;
    //此处的time是毫秒时间戳，表示这个任务具体啥时候执行

    public MyTimerTask (Runnable runnable,long delay){
        this.runnable=runnable;
        this.time=System.currentTimeMillis()+delay;
    }

    public void run(){
        runnable.run();
    }

    public long getTime(){
        return time;
    }

    @Override
    public int compareTo(MyTimerTask o) {
        // 此处这里的 - 的顺序, 就决定了这里是大堆还是小堆.
        // 此处需要小堆.
        return (int)(this.time-o.time);
    }
}

class MyTimer{
    private PriorityQueue<MyTimerTask> queue=new PriorityQueue<>();
    //如果用List不是最好的选择，在后续执行列表中任务时，需要依次遍历每个元素
    private Object locker=new Object();

    //创建线程，负责执行上述队列中的内容
    public MyTimer(){
        Thread t=new Thread(()->{
           try{
               while(true){
                   synchronized(locker){
                       while(queue.isEmpty()){
                           locker.wait();
                       }
                       MyTimerTask current=queue.peek();
                       if (System.currentTimeMillis()>=current.getTime()){
                           //执行该任务
                           current.run();
                           //将执行过的任务从队列中删除
                           queue.poll();
                       }else{
                           //暂且不执行
                           locker.wait(current.getTime()-System.currentTimeMillis());
                       }
                   }
               }
           }catch (InterruptedException e){
               throw new RuntimeException(e);
           }
        });
        t.start();
    }

    public void schedule(Runnable runnable,long delay){
        synchronized(locker){
            MyTimerTask current=new MyTimerTask(runnable,delay);
            queue.offer(current);
            locker.notify();
        }
    }


}
public class demo4 {
    public static void main(String[] args) {
        MyTimer timer=new MyTimer();

        timer.schedule(()->{
            System.out.println("倒计时 2");
        },2000);

        timer.schedule(()->{
            System.out.println("倒计时 1");
        },3000);

        timer.schedule(()->{
            System.out.println("倒计时 3");
        },1000);
        //证明优先级队列的作用
    }

    public static void main1(String[] args) {
        Timer timer=new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello 3");
            }
        },3000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello 2");
            }
        },2000);

        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("hello 1");
            }
        },1000);
    }
}
